home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 04 - 1988 / 04.02 Feb 88 / Rotate Source Code / rotString ƒ / rotString.p < prev    next >
Encoding:
Text File  |  1988-01-02  |  5.3 KB  |  218 lines  |  [TEXT/MPS ]

  1. PROGRAM rotString;
  2.  
  3. {
  4. ••••••••••••••••••••••••••••••••••
  5.     rotString by John D. Olsen
  6.                 for
  7.         MacTutor Magazine
  8.             © Jan 1988
  9. ••••••••••••••••••••••••••••••••••
  10. }
  11.  
  12. USES
  13.     {$LOAD MemQukOSToolPack}
  14.     Memtypes, Quickdraw, OSIntf, ToolIntf, PackIntf;
  15.     {$LOAD}
  16.     
  17. CONST
  18.      picDwgBeg        = 130;
  19.      picDwgEnd        = 131;
  20.      TextBegin        = 150;
  21.      TextEnd        = 151;
  22.      StringBegin    = 152;
  23.      StringEnd        = 153;
  24.      TextCenter        = 154;
  25.  
  26. TYPE
  27.      TTxtPicRec = packed Record
  28.                   tJus: Byte;
  29.                   tFlip: Byte;
  30.                   tRot: integer;
  31.                   tLine: Byte;
  32.                   tCmnt: Byte;
  33.                   end;
  34.      TTxtPicPtr = ^TTxtPicRec;
  35.      TTxtPicHdl = ^TTxtPicPtr;
  36.  
  37.      TTxtCenter = Record
  38.                   y, x: Fixed;
  39.                   end;
  40.      TTxtCenPtr = ^TTxtCenter;
  41.      TTxtCenHdl = ^TTxtCenPtr;
  42.  
  43. VAR
  44.     thehandle : handle;
  45.     windowRect, sourceRect, destRect : rect;
  46.     myWindow : windowPtr;
  47.     sourceMap, destMap, tempMap : BitMap;
  48.     myLabelStr : str255;
  49.     
  50.  
  51. FUNCTION NewPtrClear( theSize: size ) : Ptr; EXTERNAL;
  52.  
  53. PROCEDURE Rotate( srcMap, destMap : BitMap ); EXTERNAL;
  54.  
  55. PROCEDURE NewBitMapClear( VAR theBitMap : BitMap );
  56.     BEGIN
  57.     WITH theBitMap, bounds DO
  58.         BEGIN
  59.             rowBytes := ((right - left + 15) DIV 16) * 2;
  60.             baseAddr := NewPtrClear(rowBytes * (bottom - top));
  61.             IF MemError <> noErr then baseAddr := NIL;
  62.         END;
  63.     END;{NewBitMapClear}
  64.  
  65.   PROCEDURE OpenWindow;
  66.  
  67.     CONST
  68.       mBarHeightGlobal = $BAA;
  69.  
  70.     VAR
  71.       screen : rect;
  72.       mBarHeight : Integer;
  73.       MemoryPtr : ^Integer;
  74.  
  75.     BEGIN
  76.       MemoryPtr := Pointer( mBarHeightGlobal );
  77.       mBarHeight := MemoryPtr^;
  78.       screen := screenBits.bounds;
  79.       
  80.     SetRect( windowRect, screenBits.bounds.left + 5, screenBits.bounds.top
  81.             + mBarHeight + 25,screenBits.bounds.right - 5,
  82.             screenBits.bounds.bottom - 5 );    
  83.     myWindow := NewWindow( NIL, windowRect, 'Text Rotation' ,true , documentProc,
  84.                 windowPtr( -1 ), false, longint( 0 ));
  85.     SetPort( myWindow );
  86.       
  87.     END;{OpenWindow}
  88.     
  89.  
  90. PROCEDURE xDrawString( myLabelStr: str255 );
  91.  
  92.     VAR
  93.         myFontInfo: FontInfo;
  94.         strWidth, mapLength, mapHeight, xOffset, yOffset : INTEGER;
  95.         sourceMap, destMap : BitMap;
  96.         sourceRect, destRect, myClipRect : Rect;
  97.         MyRgn: RgnHandle;
  98.         origPort, offScrGrafPort : GrafPtr;
  99.         textHandle, centerHandle : Handle;
  100.         Tx, Ty: fixed;
  101.  
  102.     BEGIN
  103.         GetFontInfo(myFontInfo);
  104.         strWidth := StringWidth(myLabelStr);
  105.         mapLength := ((strWidth - 1) div 16 + 1) * 16;
  106.         mapHeight := myFontInfo.ascent + 2 * ( myFontInfo.descent );
  107.         SetRect(sourceRect, 0, 0, mapLength, mapHeight);    { set up our offscreen bitMap }
  108.         sourceMap.bounds := sourceRect;
  109.         NewBitMapClear( sourceMap );
  110.  
  111.     GetPort(origPort);        { create a new grafPort to make sure things stay clean }
  112.     offScrGrafPort := GrafPtr(NewPtr(sizeof(GrafPort)));
  113.     OpenPort(offScrGrafPort);
  114.     offScrGrafPort^.portRect := sourceMap.bounds;
  115.     SetPortBits(sourceMap);
  116.     WITH offScrGrafPort^ DO
  117.     BEGIN
  118.         txFont := origPort^.txFont;
  119.         txSize := origPort^.txSize;
  120.         txFace := origPort^.txFace;
  121.     END;
  122.  
  123.  
  124.     GetFontInfo( myFontInfo );   { draw the string we want rotated into our temp bitMap }
  125.     MoveTo( 0, myFontInfo.ascent);
  126.     DrawString( myLabelStr );
  127.  
  128.     SetPort(origPort);    { set our port back to the original }
  129.     Rotate( sourceMap, destMap );  {  rotate the offscreen bitmap }
  130.  
  131.     destRect := destMap.bounds;    { where are we going to draw it ? }
  132.     WITH destRect DO     { offset to 10,10 no matter where we start }
  133.         OffsetRect( destRect, -left, -top );    
  134.     OffsetRect( destRect, 10, 10 );
  135.  
  136.     {set up picComments }
  137.     textHandle := NewHandle(sizeof(TTxtPicRec));
  138.     centerHandle := NewHandle(sizeof(TTxtCenter));
  139.     WITH TTxtPicHdl(textHandle)^^ DO
  140.     BEGIN
  141.         tJus := 2;        {center}
  142.         tFlip := 0;    {no flip}
  143.         tRot := 270;   {rotate 270 degrees}
  144.         tLine := 1;    {single spacing}
  145.         tCmnt := 0;
  146.     END;
  147.  
  148.     HLock(centerHandle);
  149.     WITH TTxtCenHdl(centerHandle)^^, destRect DO
  150.     BEGIN
  151.         Ty := FixRatio(bottom - top, 2);
  152.         Tx := FixRatio(right - left, 2);
  153.         xOffset := - strWidth div 2;
  154.         yOffset := (myFontInfo.ascent - myFontInfo.descent) div 2;
  155.         x := FixRatio(-xOffset, 1);
  156.         y := FixRatio(-yOffset, 1);
  157.         MoveTo(left + HiWrd(Tx) + xOffset, top + HiWrd(Ty) + yOffset);
  158.     END;
  159.  
  160.     PicComment(picDwgBeg, 0, nil);
  161.     PicComment(TextBegin,  sizeof(TTxtPicRec), textHandle);
  162.     PicComment(TextCenter, sizeof(TTxtCenter), centerHandle);
  163.     HUnlock(centerHandle);
  164.     DisposHandle(centerHandle);
  165.     DisposHandle(textHandle);
  166.  
  167.     
  168.     SetRect(myClipRect, 0, 0, 0, 0);    { set myClipRect to 'nada' }
  169.     ClipRect(myClipRect);
  170.  
  171.     { this just puts the string into the picture }
  172.     DrawString(myLabelStr);
  173.  
  174.     { now set the clipRect back and draw the rotated bitmap }
  175.     ClipRect(origPort^.portRect);
  176.  
  177.     CopyBits(destMap, origPort^.portBits, destMap.bounds, destRect, srcOr, nil);
  178.     
  179.     PicComment(TextEnd, 0, nil);
  180.     PicComment(picDwgEnd, 0, nil);
  181.  
  182.     {clean up our mess}
  183.     ClosePort(offScrGrafPort);
  184.     DisposPtr(ptr(offScrGrafPort));
  185.     DisposPtr(sourceMap.baseAddr);
  186.     DisposPtr(destMap.baseAddr);
  187.     SetClip(MyRgn);
  188.     DisposeRgn(MyRgn);
  189.     END;{xDrawString}
  190.  
  191.     
  192. { • • • • • • • • • • • • • • •   M A I N   • • • • • • • • • • • • • • • }
  193. BEGIN
  194.     FlushEvents(everyEvent,0);
  195.     InitGraf(@thePort);
  196.     InitFonts;
  197.     InitWindows;
  198.     InitMenus;
  199.     InitDialogs(NIL);
  200.     InitCursor;
  201.     
  202.     OpenWindow;
  203.  
  204.     TextFont(Geneva);
  205.     TextSize(12);
  206.     TextFace([]);
  207.     
  208.     myLabelStr := 'Looking at text from a different angle';
  209.     
  210.     xDrawString( myLabelStr );
  211.  
  212.     REPEAT UNTIL button;
  213.     DisposeWindow( myWindow );
  214. END.
  215.  
  216.  
  217.  
  218.